home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
Libraries
/
Dots & Pixels
/
headers
/
screenarea.h
< prev
next >
Wrap
C/C++ Source or Header
|
1995-09-29
|
6KB
|
162 lines
#pragma once
//
// screenarea is a prototypal class for a screen area on the mac.
// It represents a square area of size x size pixels. After creating a
// screenarea one can set pixels on the screen via operator[]. An example:
//
// screenarea screen( 8);
// screen.fill();
// screen[ 3][ 3] = 34;
//
// The screenarea is always allocated on the main screen, and it is assumed
// that that screen is currently in 256-color mode. Furthermore element [ 0][ 0]
// is not located in a corner of the square, but in the center (well, almost in
// the center. One can index the rows of the array by going from -(size / 2)
// up to, but not including size - (size / 2)).
// For reasons of speed no bounds checking is implemented. It is possible
// to create a screenarea which is higher than the main screen without any
// problems, though (but not to create one which is wider than the main screen)
//
// As long as the image bounds on screen are OK it is safe to access the array
// with indices which are reasonably close to the really intended ones. The
// maximum outward offset allowed is screenarea::max_error. This constant also
// determines the maximum half_disparity allowed in 'screendots' (v.i)
//
// 941027: discovered a serious flaw in this hack while implementing 'FormExp'
// The remark regarding 'reasonably close to' is only valid regarding the array's
// x coordinates. BTW: this also means that 'add_big_dot' should not be called
// for dot positions outside the main screen.
//
// 941028: There may be some problems writing outside the 'visible screen area'
// with screenareas close to the height of the screen or higher than the screen
// when one uses the offsets returned by 'compass2offsets'. On a SuperMac
// Spectrum/8 Series II video card it was found that writing outside the screen
// caused changes in the color look-up table.
//
class screenarea
{
public:
typedef enum screen_position
{
centered, left_side, right_side
};
screenarea( int numbits, int xpos, int ypos);
screenarea( int numbits, screen_position where = centered);
~screenarea();
int any_x() const;
int any_y() const;
unsigned char *operator[]( const int index);
//
// add_circular_mask makes assumptions about the current color environment
// 'Try before you buy'. 941027: This also applies to 'add_rectangular_mask'
// 941123: Nowadays, the recommended way to obtain masks is by using simple
// Macintosh toolbox calls. 'fullscreen::fullscreen' can now make _all_
// colors associated with a window pmExplicit, so one can use
//
// PmForeColor( 74);
// PaintRect( &rect_to_fill_with_74s);
//
// to fill an area of the screen with the value '74'
//
void add_circular_mask( void);
void add_rectangular_mask( int mask_size);
void fill( const int value = 0);
void no_mask();
void add_fixation_dot( const int disparity = 0);
void add_stereo_cues( const int disparity = 0);
//
// compass2offsets takes a string containing zero or more dots and/or a
// series of letters denoting compass directions
// and turns it into a series of screen offsets.
// Every character of the string denotes a step in a state machine:
//
// eswn : move a single pixel in the indicated direction
// ESWN : include the offset of the current pixel in the list,
// then move a single pixel in the indicated direction.
// . : include the offset of the current pixel in the list, do not move.
// (the dot is included for human interface reasons. Generally one can replace
// .x by X, but .x may be easier to comprehend for some ('.e' shows
// the order 'set dot, then move', whereas 'E' doesn't)
//
// compass2offsets returns both a list of offsets and an integer denoting
// the length of that list. The 'maxnum' parameter is also used as input
// to signal the length of the 'offsets' array. As a special case one can
// pass zero to offsets. In that case maxnum is set to the size 'offsets'
// needs to have in order to accomodate the list specified by 'compass'.
// maxnum is always set to the actual number of offsets needed, but the
// offsets array is never filled with more offsets than were specified
// in the *maxnum parameter.
//
// Examples:
// .e.s.w. creates 2x2 square dots to the bottom-right of the 'real' dot
// .e.n.w. creates 2x2 square dots to the top-right of the 'real' dot
//
// ww.e.e.e.e.
// wwEEEE.
// wwEEEEN these all create 5x1 bars centered at the dot position
// 2w4E.
// 12w10e4E.
//
void compass2offsets( const char *compass, int *offsets, int *maxnum);
protected:
const int size;
const int half_size;
const int shiftbits;
const int coord_shift;
//
// 940823: compass2offsets needs to know rowBytes => it no longer is
// a local variable in 'init'. Instead it gets set by init.
//
int rowBytes;
//
// screen row pointers:
//
unsigned char **screen;
unsigned char *waste_area;
static const int max_error;
void init( int xpos, int ypos);
private:
//
// add_big_dot has not been debugged. It seems to work for use by
// add_fixation_dot and add_stereo_cues.
//
void add_big_dot( const int x, const int y, const int disparity = 0);
};
inline unsigned char * screenarea::operator[]( const int index)
{
return screen[ index];
}
inline screenarea::screenarea( int numbits, int xpos, int ypos)
: size( 1 << numbits)
, half_size( 1 << (numbits - 1))
, shiftbits( 2 * numbits - 9)
, coord_shift( 16 - numbits)
{
init( xpos, ypos);
}
inline void screenarea::no_mask()
{
fill( 128);
}
inline int screenarea::any_x() const
{
return (randomizer_step() % size) - half_size;
}
inline int screenarea::any_y() const
{
return (randomizer_step() % size) - half_size;
}